package de.karlNet.sshTray.datasources;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import de.karlNet.sshTray.model.Connection;

@Component
public class LocalFile implements IDataSource {
	@Autowired
	private List<IChangeListener> changeListeners;
	private XStream xStream = new XStream(new DomDriver());
	private File file = new File("connections");

	public List<Connection> readConnections() {
		FileReader reader = null;
		try {
			reader = new FileReader(file);
			@SuppressWarnings("unchecked")
			List<Connection> connections = (List<Connection>) xStream
					.fromXML(reader);
			reader.close();
			return connections;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			try {
				reader.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		return new ArrayList<Connection>();
	}

	public void createOrUpdateConnection(Connection connection) {
		List<Connection> connections = this.readConnections();
		if (connection.getId() == null) {
			connection.setId(UUID.randomUUID().getLeastSignificantBits());
			connections.add(connection);
		} else {
			int index = connections.indexOf(connection);
			connections.remove(index);
			connections.add(index, connection);
		}
		writeData(connections);
	}

	public LocalFile() {
		if(!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} 
	}

	public int getCount() {
		return this.readConnections().size();
	}

	public void deleteConnection(Connection con) {
		List<Connection> connections = this.readConnections();
		if (connections.remove(con)) {
			writeData(connections);
		} else {
			throw new IndexOutOfBoundsException("Element not found");
		}
	}

	private void writeData(List<Connection> connections) {

		FileWriter fileReader;
		try {
			fileReader = new FileWriter(file);
			xStream.toXML(connections, fileReader);
			fileReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.notifyChangeListeners();
	}

	public void moveConnectionUp(Connection connection) {
		List<Connection> connections = this.readConnections();
		int indexOfSelected = connections.indexOf(connection);
		if (indexOfSelected > 0) {
			Collections.swap(connections, indexOfSelected, indexOfSelected - 1);
		}
		writeData(connections);
	}

	public void moveConnectionDown(Connection connection) {
		List<Connection> connections = this.readConnections();
		int indexOfSelected = connections.indexOf(connection);
		if (indexOfSelected < connections.size()) {
			Collections.swap(connections, indexOfSelected, indexOfSelected + 1);
		}
		writeData(connections);
	}


	private void notifyChangeListeners() {
		for (IChangeListener changeListener : this.changeListeners) {
			changeListener.dataHasBeenUpdated();
		}
	}
}
